﻿using DotNetty.Transport.Channels;
using DotNetty.Transport.Channels.Groups;
using iTool.ClusterComponent;
using System.Collections.Concurrent;

namespace DotNetty.Framework
{
    /// <summary>
    /// 为Channel绑定Client信息
    /// </summary>
    public static class ExtendClientInfo
    {
        internal static ConcurrentDictionary<IChannel, string> dictionaryClientByChannel;
        internal static ConcurrentDictionary<IChannel, ConnectorInfo> dictionaryClientByUUID;

        //internal static ConcurrentDictionary<IChannel, ConcurrentDictionary<string, IAsyncObserver<string>>> dictionaryObserverByChannel;

        //static ConcurrentDictionary<IChannel, string> dictionaryHostByChannelString;

        static ExtendClientInfo()
        {
            dictionaryClientByChannel = new ConcurrentDictionary<IChannel, string>();
            dictionaryClientByUUID = new ConcurrentDictionary<IChannel, ConnectorInfo>();
            //dictionaryHostByChannelString = new ConcurrentDictionary<IChannel, string>();
            //dictionaryObserverByChannel = new ConcurrentDictionary<IChannel, ConcurrentDictionary<string, IAsyncObserver<string>>>();
        }

        /// <summary>
        /// 获取Channel信息
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static string GetChannel(this IChannelHandlerContext context)
        {
            return GetChannel(context.Channel);
        }
        public static string GetChannel(this IChannel channel)
        {

            if (dictionaryClientByChannel.ContainsKey(channel))
            {
                dictionaryClientByChannel.TryGetValue(channel, out string value);
                return value;
            }

            return default;
        }



        /// <summary>
        /// 获取IChannel信息
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static IChannelGroup GetChannelByChannelString(this IChannelHandlerContext context, string channel)
        {
            context.GetGroupByChannel(channel, out IChannelGroup group);
            return group;
        }


        /// <summary>
        /// 写入客户端信息
        /// </summary>
        /// <param name="context"></param>
        /// <param name="client"></param>
        public static void BindChannel(this IChannelHandlerContext context, string channel)
        {
            if (!dictionaryClientByChannel.ContainsKey(context.Channel))
            {
                if (!dictionaryClientByChannel.TryAdd(context.Channel, channel))
                {
                    dictionaryClientByChannel.TryAdd(context.Channel, channel);
                }
            }
            else
            {
                dictionaryClientByChannel[context.Channel] = channel;
            }

            context.Subscribe(channel);
        }

        /// <summary>
        /// 删除客户端信息
        /// </summary>
        /// <param name="context"></param>
        public static string ClearChannel(this IChannelHandlerContext context)
        {
            return ClearChannel(context.Channel);
        }

        public static string ClearChannel(this IChannel channel)
        {
            if (dictionaryClientByChannel.ContainsKey(channel))
            {
                // 卸载订阅
                channel.UnSubscribeByChannel();
                dictionaryClientByChannel.TryRemove(channel, out string value);
                return value;
            }

            return string.Empty;
        }


        public static ConnectorInfo GetClientUUID(this IChannelHandlerContext context)
        {
            return GetClientUUID(context.Channel);
        }
        public static ConnectorInfo GetClientUUID(this IChannel channel)
        {

            if (dictionaryClientByUUID.ContainsKey(channel))
            {
                dictionaryClientByUUID.TryGetValue(channel, out ConnectorInfo uuid);
                return uuid;
            }

            return default;
        }

        public static void BindClientUUID(this IChannelHandlerContext context, ConnectorInfo uuid)
        {
            if (!dictionaryClientByUUID.ContainsKey(context.Channel))
            {
                if (!dictionaryClientByUUID.TryAdd(context.Channel, uuid))
                {
                    dictionaryClientByUUID.TryAdd(context.Channel, uuid);
                }
            }
            else
            {
                dictionaryClientByUUID[context.Channel] = uuid;
            }
        }
        public static ConnectorInfo ClearClientUUID(this IChannelHandlerContext context)
        {
            return ClearClientUUID(context.Channel);
        }
        public static ConnectorInfo ClearClientUUID(this IChannel channel)
        {
            if (dictionaryClientByUUID.ContainsKey(channel))
            {
                dictionaryClientByUUID.TryRemove(channel, out ConnectorInfo uuid);
                return uuid;
            }
            return default;
        }

    }
}
